/**
 * This module handle DataSportsApi's xml files
 */

var fs = require('fs'), xml2js = require('xml2js') , util = require('util');;

/**
 * Return all the group matches id 
 */
var getMatchesIdByGroup = function(xmlFile, group, callback) {
	var parser = new xml2js.Parser();
	var matches = [];
	console.log(xmlFile);
	fs.readFile(xmlFile, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				console.dir('result: ' + result);
				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					if (result.schedule.matches[0].match[i].tournament[0].$.name == "World Cup, Group " + group) {
						matches.push(result.schedule.matches[0].match[i].$.id)
					}
				}

				callback(matches);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getMatchesIdByGroup, check xmlFile path " + err);
			callback(err);    		
		}
	});
};


/**
 * This function sends a mapping of matches to team Names by the input of the level, take this from the schedule (which is updated)
 * This function will eventually go to the client side and be stored in his localStorage so he can map from match_ids to team names
 * @param path to schedule.xml
 * @param level to map
 * @return an array of objects : {match_id:<value> , teams:[<home teamName> , <away teamName>]}
 */
var getMapMatchesByLevel = function(filePath , level , callback) {
	var parser = new xml2js.Parser();
	var matches = [];

	fs.readFile(filePath, function(err, data) {
		try{
			parser.parseString(data, function(err, result){

				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					if (result.schedule.matches[0].match[i].tournament[0].$.name == "Knockout stage") {
						if (result.schedule.matches[0].match[i].round[0].$.number == level) {
							matches.push({
								match_id : result.schedule.matches[0].match[i].$.id,
								teams : [result.schedule.matches[0].match[i].home[0].$.name, result.schedule.matches[0].match[i].away[0].$.name]
							})

						}
					}
					else if(level == 0){
						matches.push({
							match_id : result.schedule.matches[0].match[i].$.id,
							teams : [result.schedule.matches[0].match[i].home[0].$.name, result.schedule.matches[0].match[i].away[0].$.name]
						})
					}
				}

				callback(matches);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getMapMatchesByLevel, check xmlFile path " + err);
			callback(err);    		
		}
	});
};

/**
 * This function return the first and last match of each knockout level
 * { level : <number>, first : <Date>, last : <Date>}
 */
var getLevelFirstLastMatchForCronJob = function(filePath , callback) {
	var parser = new xml2js.Parser();
	var matches = [];

	fs.readFile(filePath, function(err, data) {
		try{
			parser.parseString(data, function(err, result){

				var groupLevelFlag, levelNumberTmp, firstTmp, lastTmp;

				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					if (result.schedule.matches[0].match[i].tournament[0].$.name !== "Knockout stage") {
						if (groupLevelFlag == null) {
							groupLevelFlag = true;
							firstTmp = result.schedule.matches[0].match[i].$.scheduled;
						}
						lastTmp = result.schedule.matches[0].match[i].$.scheduled;
					}
					else if (result.schedule.matches[0].match[i].round[0].$.name !== '3rd') {

						if(levelNumberTmp == null ){
							matches.push({
								level : 0,
								first : firstTmp,
								last : lastTmp
							});

							levelNumberTmp = result.schedule.matches[0].match[i].round[0].$.number;
							firstTmp = result.schedule.matches[0].match[i].$.scheduled;

						}
						else if (levelNumberTmp > result.schedule.matches[0].match[i].round[0].$.number) {
							matches.push({
								level : levelNumberTmp,
								first : firstTmp,
								last : lastTmp
							});
							levelNumberTmp =  result.schedule.matches[0].match[i].round[0].$.number;
							firstTmp = result.schedule.matches[0].match[i].$.scheduled;
							if(levelNumberTmp == 1){
								matches.push({
									level : levelNumberTmp,
									first : firstTmp,
									last : firstTmp
								});	
							}
						}

						lastTmp = result.schedule.matches[0].match[i].$.scheduled;
					}
				}
				callback(matches);
			});
		}
		catch(err){
			console.dir("can not read the xml file in method getLevelFirstLastMatchForCronJob, check xmlFile path " + err);
			callback(err);    		
		}
	});
};

/**
 * Return match information by this format - {match_id : __,	home : ____, away : ____, date : ___, status : ___,	score : ____,winner : ___}
 * Followed by the game status:
 * scheduled -->  score, winner = undefined
 * closed --> score and winner set,
 * inprogress -->  score set, winner undefined.
 * @param data - match boxscore path file
 */
var getMatchBoxscore = function(filePath, callback) {
	var parser = new xml2js.Parser();

	fs.readFile(filePath, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var match;

				var home = result.boxscore.matches[0].match[0].home[0].$.name
				var away = result.boxscore.matches[0].match[0].away[0].$.name;
				var status = result.boxscore.matches[0].match[0].$.status; //check the game status
				var score, winner;
				//if the game started, get the score.
				if(status !== "scheduled"){
					var homeScore = parseInt(result.boxscore.matches[0].match[0].home[0].$.score, 10);
					var awayScore = parseInt(result.boxscore.matches[0].match[0].away[0].$.score, 10);
					score = [homeScore, awayScore];
					if(status === "closed"){
						if(homeScore > awayScore){
							winner = home;
						} else if (home < away) {
							winner = away;
						} else {
							winner = "draw"
						}

					}
				}
				
				match = {
						match_id : result.boxscore.matches[0].match[0].$.id,
						home : home,
						away : away,
						date : result.boxscore.matches[0].match[0].$.scheduled,
						status : result.boxscore.matches[0].match[0].$.status,
						score : score,
						winner : winner,
						level : result.boxscore.matches[0].match[0].round[0].$.number
				};
				callback(match);
			});
		}
		catch(err){
			console.dir("can not read the xml file in method getMatchFromSchedById, check xmlFile path " + err);
			callback(err);    		
		}	
	});


};

/**
 * Return an a object {match_id: value , date: value , home: value , away: value}
 */
var getMatchFromSchedById = function(filePath, _match_id, callback) {
	var parser = new xml2js.Parser();

	fs.readFile(filePath, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var matchInfo,match_id;

				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					match_id = result.schedule.matches[0].match[i].$.id;

					if (match_id == _match_id) {
						matchInfo = {
								match_id : _match_id,
								date : result.schedule.matches[0].match[i].$.scheduled,
								home : result.schedule.matches[0].match[i].home[0].$.name,
								away : result.schedule.matches[0].match[i].away[0].$.name
						};
					}
				}

				callback(matchInfo);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getMatchFromSchedById, check xmlFile path " + err);
			callback(err);    		
		}	
	});
};


/**
 * Return list with all the group matches by this format - 	{match_id : ____, groupName : _____, date : ______}
 */
var getGroupMatches = function(xmlFile, callback) {
	var parser = new xml2js.Parser();
	var matchesArr = [];

	fs.readFile(xmlFile, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var tournamentName;

				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					tournamentName = result.schedule.matches[0].match[i].tournament[0].$.name;
					if (tournamentName !== "Knockout stage") {
						matchesArr.push({
							match_id : result.schedule.matches[0].match[i].$.id,
							groupName : tournamentName,
							date : result.schedule.matches[0].match[i].$.scheduled
						});
					}
				}

				callback(matchesArr);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getGroupMatches, check xmlFile path " + err);
			callback(err);    		
		}	
	});
};


/**
 * Return list with all the knockout matches by this format - 	{match_id : ____, level : _____, date : ____, home: false, away : false}
 */
var getKnockoutMatches = function(xmlFile, callback) {
	var parser = new xml2js.Parser();
	var matchesArr = [];

	fs.readFile(xmlFile, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var tournamentName;
				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					tournamentName = result.schedule.matches[0].match[i].tournament[0].$.name;
					if (tournamentName === "Knockout stage") {
						matchesArr.push({
							match_id : result.schedule.matches[0].match[i].$.id,
							level : parseInt(result.schedule.matches[0].match[i].round[0].$.number,10),
							date : result.schedule.matches[0].match[i].$.scheduled,
							home : false,
							away : false
						});
					}
				}
				callback(matchesArr);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getKnockoutMatches, check xmlFile path " + err);
			callback(err);    		
		}	
	});
};


/**
 * Return callback function with teams array : {team_id: ____, team_name: ___}
 */
var getTeams = function (xmlFile, callback){

	var parser = new xml2js.Parser();	
	var teamsArr =[];

	fs.readFile(xmlFile, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var tournamentName ;

				for (var i = 0; i < result.hierarchy.category[0].tournament_group[0].tournament.length; i++) {
					tournamentName =  result.hierarchy.category[0].tournament_group[0].tournament[i].$.name;

					if(tournamentName !== "World Cup, Knockout stage"){
						for (var j = 0; j < result.hierarchy.category[0].tournament_group[0].tournament[i].team.length; j++) {
							teamsArr.push({
								team_id:  result.hierarchy.category[0].tournament_group[0].tournament[i].team[j].$.id, 
								team_name: result.hierarchy.category[0].tournament_group[0].tournament[i].team[j].$.name});
						}
					}
				}
				callback(teamsArr);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getTeams, check xmlFile path " + err);
			callback(err);    		
		}	
	});
};


/**
 * Return callback function with groups Qualifiers array : {groupName: ____, team1: ___ , team2 : ___}
 */
var getQualifiersFromStanding = function (xmlFile, group_name, callback){
	var groupsQualifiersArr ;
	var parser = new xml2js.Parser();
	fs.readFile(xmlFile, function(err, data) {
		try{
			parser.parseString(data, function(err, result){

				for (var i = 0; i < result.standings.categories[0].category[0].tournament_group[0].tournament.length; i++) {
					if(result.standings.categories[0].category[0].tournament_group[0].tournament[i].$.name == group_name){
						groupsQualifiersArr = {
								groupName : result.standings.categories[0].category[0].tournament_group[0].tournament[i].$.name,
								rankedFirst : result.standings.categories[0].category[0].tournament_group[0].tournament[i].team[0].$.name,
								rankedSecond : result.standings.categories[0].category[0].tournament_group[0].tournament[i].team[1].$.name
						};
						break;
					}

				}
				callback(groupsQualifiersArr);

			});
		}
		catch(err){
			console.dir("can not read the xml file in method getQualifiersFromStanding, check xmlFile path " + err);
			callback(err);    		
		}	
	});
};


/**
 * Returns the next match_id from the schedule.xml for this team_name
 * home - is if the team is playing at home
 */
var getNextMatchByTeamName = function(xmlFile, team_name , level, callback){
	var parser = new xml2js.Parser();
	var match;
	fs.readFile(xmlFile, function(err, data) {
		try{
			parser.parseString(data, function(err, result){

				var match_date, homeTeamName, awayTeamName, match_scheduled, tempMatchDate ;
				var nowDate = new Date();

				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					if(result.schedule.matches[0].match[i].tournament[0].$.name == "World Cup, Knockout stage"){

						if (result.schedule.matches[0].match[i].round[0].$.number == level) {
							match_scheduled = result.schedule.matches[0].match[i].$.status;
							tempMatchDate = new Date(result.schedule.matches[0].match[i].$.scheduled);
							if (tempMatchDate > nowDate) {

								homeTeamName = result.schedule.matches[0].match[i].home[0].$.name;
								awayTeamName = result.schedule.matches[0].match[i].away[0].$.name;

								if (team_name === homeTeamName) {

									match_date = tempMatchDate;
									match = {
											team_name : team_name,
											match_id : result.schedule.matches[0].match[i].$.id,
											home : true
									};
									break;

								} else if (team_name === awayTeamName) {
									match_date = tempMatchDate;
									match = {
											team_name : team_name,
											match_id : result.schedule.matches[0].match[i].$.id,
											home : false,
									};
									break;
								}
							}
						}
					}
				}
				//console.log(match);
				callback(match);
			});
		}
		catch(err){
			console.dir("can not read the xml file in method getNextMatchByTeamName, check xmlFile path " + err);
			callback(err);    		
		}
	});
};
/**
 * Lists all the matches in this date - get it from schedule that is passed as a parameter
 * @param path to resources
 * @param date object that looks like this - "Wed May 14 2014 21:21:30 GMT+0300 (IDT)" 
 * @return array of matches {match_id:<value> , date:<date>}
 */
var getMatchesByDate = function(path , date , callback){
	var parser = new xml2js.Parser();
	var matchesArr = [];

	fs.readFile(path, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var day = new Date(date);
				var DayTmp;
				for (var i = 0; i < result.schedule.matches[0].match.length; i++) {
					DayTmp = new Date(result.schedule.matches[0].match[i].$.scheduled);
//					(DayTmp.getDate() == day.getDate() 
//					&& DayTmp.getMonth() == day.getMonth()
//					&& DayTmp.getFullYear() == day.getFullYear())
					if (DayTmp.getUTCDate() == day.getUTCDate() && DayTmp.getMonth() == day.getMonth() && DayTmp.getFullYear() == day.getFullYear()) {
						matchesArr.push({
							match_id : result.schedule.matches[0].match[i].$.id,
							date : result.schedule.matches[0].match[i].$.scheduled
						});
					}
				}
				callback(matchesArr);
			});
		}
		catch(err){
			console.dir("can not read the xml file in method getMatchesByDate, check xmlFile path " + err);
			callback(err);    		
		}	
	});
};
/**
 * Scans the hierarchy.xml file (the path is passed as the first param)
 * returns an array of objects - {groupName:<World Cup, Group...> , teams:[<team1>,<team2>,<team3>,<team4>]}
 * the objects in the team array are the TEAM NAMES, not the IDs.
 */
var mapQualifiersFromHierarchy = function (filePath,callback){
	var parser = new xml2js.Parser();	
	var groupsArr  =[];

	fs.readFile(filePath, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var tournamentName, splitName;

				for (var i = 0; i < result.hierarchy.category[0].tournament_group[0].tournament.length; i++) {
					tournamentName =  result.hierarchy.category[0].tournament_group[0].tournament[i].$.name;
					if(tournamentName !== "World Cup, Knockout stage"){
						var teamsArr = [];
						for (var j = 0; j < result.hierarchy.category[0].tournament_group[0].tournament[i].team.length; j++) {
							teamsArr.push(
									result.hierarchy.category[0].tournament_group[0].tournament[i].team[j].$.name);
						}
						groupsArr.push({
							groupName : tournamentName,
							teams : teamsArr
						});
					}
				}
				callback(groupsArr);
			});
		}
		catch(err){
			console.dir("can not read the xml file in method mapQualifiersFromHierarchy, check xmlFile path " + err);
			callback(err);    		
		}
	});
};

/**
 * Scans the hierarchy.xml file (the path is passed as the first param)
 * returns  {tournamentName : <World Cup, Group...> , season_end : <Date>}
 */
var getEndTimeOftournaments = function (filePath,callback){
	var parser = new xml2js.Parser();	
	var groupsArr  =[];

	fs.readFile(filePath, function(err, data) {
		try{
			parser.parseString(data, function(err, result){
				var season_end;

				for (var i = 0; i < result.hierarchy.category[0].tournament_group[0].tournament.length; i++){
					groupsArr.push({
						tournamentName : result.hierarchy.category[0].tournament_group[0].tournament[i].$.name,
						season_end :  result.hierarchy.category[0].tournament_group[0].tournament[i].$.season_end
					});
				}
				callback(groupsArr);
			});
		}
		catch(err){
			console.dir("can not read the xml file in method mapQualifiersFromHierarchy, check xmlFile path " + err);
			callback(err);    		
		}
	});
};



exports.getKnockoutMatches = getKnockoutMatches;
exports.getGroupMatches = getGroupMatches;
exports.getTeams = getTeams ;
exports.getMatchBoxscore = getMatchBoxscore;
exports.getQualifiersFromStanding = getQualifiersFromStanding;
exports.getNextMatchByTeamName = getNextMatchByTeamName;
exports.getMapMatchesByLevel = getMapMatchesByLevel;
exports.getMatchesByDate = getMatchesByDate;
exports.getEndTimeOftournaments = getEndTimeOftournaments;
exports.mapQualifiersFromHierarchy = mapQualifiersFromHierarchy;
exports.getLevelFirstLastMatchForCronJob = getLevelFirstLastMatchForCronJob;
exports.getMatchFromSchedById = getMatchFromSchedById;

//##########################################################################################
//####################################    Test xmlUtils ####################################
//##########################################################################################
var testXmlUtils = function(funcToTest){

	switch (funcToTest) {
	case "getQualifiersFromStanding":getQualifiersFromStanding(__dirname + '/resources/standing.xml', 'World Cup, Group A' ,function(result){
		console.dir(" --------- getQualifiersFromStanding ---------------");
		console.dir(result);
	});
	break;
	case "getTeams" : getTeams(__dirname + '/resources/hierarchy.xml',function(result){
		console.dir(" --------- getTeams ---------------");
		console.dir(result);
	});
	break;
	case "mapQualifiersFromHierarchy" : mapQualifiersFromHierarchy(__dirname + '/resources/hierarchy.xml',function(result){
		console.dir(" --------- mapQualifiersFromHierarchy ---------------");
		console.log(util.inspect(result, false, null));

	});
	break;
	case "getEndTimeOftournaments" : getEndTimeOftournaments(__dirname + '/resources/hierarchy.xml',function(result){
		console.dir(" --------- getEndTimeOftournaments ---------------");
		console.log(util.inspect(result, false, null));

	});
	getEndTimeOftournaments
	break;
	case "getKnockoutMatches" : getKnockoutMatches(__dirname + '/resources/schedule.xml',function(result){
		console.dir(" --------- getKnockoutMatches ---------------");
		console.dir(result);
	});
	break;
	case "getLevelFirstLastMatchForCronJob" : getLevelFirstLastMatchForCronJob(__dirname + '/resources/schedule.xml',function(result){
		console.dir(" --------- getLevelFirstLastMatchForCronJob---------------");
		console.dir(result);
	});
	break;
	case "getMapMatchesByLevel" : getMapMatchesByLevel(__dirname + '/resources/schedule.xml',0,function(result){
		console.dir(" --------- getMapMatchesByLevel ---------------");
		console.dir(result);
	});
	break;
	case "getGroupMatches" : getGroupMatches(__dirname + '/resources/schedule.xml',function(result){
		console.dir(" --------- getGroupMatches ---------------");
		console.dir(result);
	});
	break;
	case "getMatchesByDate" : getMatchesByDate(__dirname + '/resources/schedule.xml',"2014-06-23T16:00:00Z",function(result){
		console.dir(" --------- getMatchesByDate ---------------");
		console.dir(result);
	});
	break;
	case "getMatchFromSchedById" : getMatchFromSchedById("03702fc0-6f31-4b66-aeef-ffff98cc033b",function(result){
		console.dir(" --------- getMatchFromSchedById ---------------");
		console.dir(result);
	});
	break;
	case "getMatchBoxscore" : getMatchBoxscore(__dirname + '/resources/boxscore.xml', function(data) {
		console.dir(" --------- getMatchBoxscore ---------------");
		console.dir(data);
	});
	break;
	case "getMatchesIdByGroup" : getMatchesIdByGroup(__dirname + '/resources/scheduleTest.xml','A',function(result){
		console.dir(" --------- getMatchesIdByGroup ---------------");
		console.dir(result);
	});
	break;
	case "getNextMatchByTeamName" : getNextMatchByTeamName(__dirname + '/resources/schedule.xml',"Brazil", 4, function(result){
		console.dir(" --------- getNextMatchByTeamName ---------------");
		console.dir(result);
	});
	break;
	default: console.dir("input paramemter is not a valid function");
	break;
	}
};
var testAllXmlUtils = function(){
	testXmlUtils("getQualifiersFromStanding");
	testXmlUtils("getTeams");
	testXmlUtils("getKnockoutMatches");
	testXmlUtils("getGroupMatches");
	testXmlUtils("getMatchFromSchedById");
	testXmlUtils("getMatchBoxscore");
	testXmlUtils("getMatchesIdByGroup");
	testXmlUtils("getNextMatchByTeamName");
	testXmlUtils("getMapMatchesByLevel");
	testXmlUtils("getMatchesByDate");
	testXmlUtils("mapQualifiersFromHierarchy");
	testXmlUtils("getEndTimeOftournaments");
	testXmlUtils("getLevelFirstLastMatchForCronJob");
};
//testAllXmlUtils();

